package com.black.platform.role.service.handler.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.black.common.web.PageQuery;
import com.black.platform.dictionary.po.Dictionary;
import com.black.platform.dictionary.service.handler.DictionaryHandlerService;
import com.black.platform.permission.po.Permission;
import com.black.platform.role.po.RolePermission;
import com.black.platform.role.service.bz.RolePermissionService;
import com.black.platform.role.po.Role;
import com.black.platform.role.service.bz.RoleService;
import com.black.platform.role.service.handler.RoleHandlerService;
import com.black.platform.role.vo.IdVo;
import com.black.platform.role.vo.RolePermissionVo;
import com.black.platform.role.vo.RoleTreeVo;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class RoleHandlerServiceImpl implements RoleHandlerService {

    private final RoleService roleService;

    private final RolePermissionService rolePermissionService;

    private final DictionaryHandlerService dictionaryHandlerService;

    @Override
    public List<Role> getUserAllRoleByUserId(Long userId) {
        return null;
    }

    @Override
    public IPage<Role> search(PageQuery<Role> searchVo) {
        Role queryData = searchVo.getQueryData();
        QueryWrapper<Role> query = new QueryWrapper<>();
        if (!StringUtils.isEmpty(queryData.getValid())) {
            query.eq("valid", queryData.getValid());
        }
        if (!StringUtils.isEmpty(queryData.getRoleName())) {
            query.eq("role_name", queryData.getRoleName());
        }
        return roleService.page(searchVo.getPager(), query);
    }

    @Override
    public RolePermissionVo getRolePermissionVoByRoleId(Long roleId) {
        RolePermissionVo rolePermissionVo = new RolePermissionVo();
        Role role = roleService.getById(roleId);
        rolePermissionVo.setRole(role);
        QueryWrapper<RolePermission> query = new QueryWrapper<>();
        query.eq("role_id", roleId);
        List<Permission> rolePermissionList = rolePermissionService.getPermissionByRoleId(roleId);
        System.out.println(rolePermissionList);
        List<IdVo> permissionIds = rolePermissionList.stream().filter(p -> p != null && !"data".equals(p.getPermissionType())).map(rolePermission -> new IdVo(rolePermission.getId())).distinct().collect(Collectors.toList());
        List<IdVo> dataPermissionIds = rolePermissionList.stream().filter(p -> p != null && "data".equals(p.getPermissionType())).map(rolePermission -> new IdVo(rolePermission.getId())).distinct().collect(Collectors.toList());
        rolePermissionVo.setViewPermissionIds(permissionIds);
        rolePermissionVo.setDataPermissionIds(dataPermissionIds);
        return rolePermissionVo;
    }

    @Override
    @Transactional
    @CacheEvict(value = {"UserMenu", "UserPermission"}, allEntries = true)
    public boolean saveOrUpdate(RolePermissionVo rolePermissionVo) {
        if (rolePermissionVo.getRole().getId() != null) {
            QueryWrapper<RolePermission> query = new QueryWrapper<>();
            query.eq("role_id", rolePermissionVo.getRole().getId());
            rolePermissionService.remove(query);
        }
        roleService.saveOrUpdate(rolePermissionVo.getRole());
        if (rolePermissionVo.getViewPermissionIds() != null) {
            rolePermissionVo.getViewPermissionIds().addAll(rolePermissionVo.getDataPermissionIds());
        }
        if (rolePermissionVo.getViewPermissionIds() != null && rolePermissionVo.getViewPermissionIds().size() > 0) {
            List<RolePermission> rolePermissionList = rolePermissionVo.getViewPermissionIds().stream().distinct().map(permissionIdVo -> {
                RolePermission rolePermission = new RolePermission();
                rolePermission.setPermissionId(permissionIdVo.getId());
                rolePermission.setRoleId(rolePermissionVo.getRole().getId());
                return rolePermission;
            }).collect(Collectors.toList());
            rolePermissionService.saveBatch(rolePermissionList);
        }
        return true;
    }

    @Override
    public List<RoleTreeVo> getAllRoleTree(String systemCode) {
        List<RoleTreeVo> roleTreeVoList = new ArrayList<>();
        List<Role> roleList;
        QueryWrapper<Role> query = new QueryWrapper<>();
        if (!StringUtils.isEmpty(systemCode)) {
            query.eq("system_code", systemCode);
            roleList = roleService.list(query);
        } else {
            roleList = roleService.list();
        }

        List<Dictionary> dictionaryList = dictionaryHandlerService.getByCodeType("systemCode", false);
        if (roleList != null && roleList.size() > 0) {
            dictionaryList.forEach(dictionary -> {
                RoleTreeVo roleTreeVo = new RoleTreeVo();
                roleTreeVo.setTitle(dictionary.getName());
                roleTreeVo.setExpand(true);
                roleTreeVo.setChildren(new ArrayList<>());
                roleList.stream().filter(role -> dictionary.getCode().equals(role.getSystemCode()))
                        .forEach(role -> {
                            RoleTreeVo treeVo = new RoleTreeVo();
                            treeVo.setId(role.getId());
                            treeVo.setTitle(role.getRoleName());
                            roleTreeVo.getChildren().add(treeVo);
                        });
                if (roleTreeVo.getChildren().size() == 0) {
                    roleTreeVo.setDisabled(true);
                    roleTreeVo.setExpand(false);
                    roleTreeVo.setChildren(null);
                }
                roleTreeVoList.add(roleTreeVo);
            });
        }
        return roleTreeVoList;
    }
}
